package kiang.teb;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

/**
 * Copyright (c) 2014 by kiang
 *
 * @author kiang
 * @version 0.1-pre
 */
public final class TebReport {
    //    <td valign="bottom"><div class="panel" style="height:10px;background-color:#45b97c;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:20px;background-color:#ffd400;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:30px;background-color:#f47920;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:40px;background-color:#b2d235;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:50px;background-color:#6a6da9;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:60px;background-color:#ef5b9c;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:70px;background-color:#7fb80e" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:80px;background-color:#999d9c;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:90px;background-color:#1d953f;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:100px;background-color:#d71345;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:100px;background-color:#843900" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:100px;background-color:#78a355;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:100px;background-color:#145b7d;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:100px;background-color:#c37e00;" title="1000"></td>
    //    <td valign="bottom"><div class="panel" style="height:100px;background-color:#293047" title="1000"></td>
    private static final String[] COLORS = new String[]{
            "#45b97c;", "#ffd400;", "#f47920;", "#b2d235;", "#6a6da9;",
            "#ef5b9c;", "#7fb80e;", "#999d9c;", "#1d953f;", "#d71345;",
            "#843900;", "#78a355;", "#145b7d;", "#c37e00;", "#293047;"
    };

    static interface PanelRender {
        public String getTitle();

        public long getValue(TebResult[] results, int index);
    }

    public static BufferedWriter writeHead(File file, Properties properties) throws Exception {
        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
        String date = new SimpleDateFormat("yyy-MM-dd hh:mm:ss").format(new Date());
        TebUtilities.println(bw, "<!DOCTYPE html>");
        TebUtilities.println(bw, "<!DOCTYPE html>");
        TebUtilities.println(bw, "<head>");
        TebUtilities.println(bw, "<title>RPT" + properties.getProperty("thread") + "</title>");
        TebUtilities.println(bw, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>");
        TebUtilities.println(bw, "<style type=\"text/css\">");
        TebUtilities.println(bw, "    html, body, td, div { padding: 0px; margin: 0px; font-size: 9pt;}");
        TebUtilities.println(bw, "    table.panel { width: 250px; height: 160px; border: 1px solid #000000; margin-left: 1px; margin-right: 1px;}");
        TebUtilities.println(bw, "    table.legend { width: 250px; margin-left: 1px; margin-right: 1px; border-left: 1px solid #000000; border-bottom: 1px solid #000000;}");
        TebUtilities.println(bw, "    table.info { width: 1008px; margin-left: 1px; margin-right: 1px; border-left: 1px solid #000000; border-bottom: 1px solid #000000;}");
        TebUtilities.println(bw, "    td.legend { border-top: 1px solid #000000; border-right: 1px solid #000000; }");
        TebUtilities.println(bw, "    div.title { padding-top:5px; font-weight:600; font-size: 11pt; color:blue; text-align:center; }");
        TebUtilities.println(bw, "    div.subject { font-weight:600; font-size: 10pt; color:red; text-align:center; }");
        TebUtilities.println(bw, "    div.panel { width: 15px; margin-left: 2px; margin-right: 2px; }");
        TebUtilities.println(bw, "    div.legend { width: 12px; height: 12px; }");
        TebUtilities.println(bw, "</style>");
        TebUtilities.println(bw, "</head>");
        TebUtilities.println(bw, "<body>");
        TebUtilities.println(bw, "<div class=\"title\">Template Engine Benchmark V1.0.0 Author:kiang Test Date:" + date + "</div>");
        TebUtilities.println(bw, "<hr width=\"1010px\"/>");
        return bw;
    }

    public static void writeTail(BufferedWriter bw) throws Exception {
        try {
            TebUtilities.println(bw, "</body>");
            TebUtilities.println(bw, "</html>");
        } finally {
            if (bw != null) {
                bw.close();
            }
        }
    }

    public static void writeBody(BufferedWriter bw, Properties properties, final boolean binary, String target, TebResult[] results) throws Exception {
        final int thread = Integer.parseInt(properties.getProperty("thread"));
        final int record = Integer.parseInt(properties.getProperty("record"));
        final int warmed = Integer.parseInt(properties.getProperty("warmed"));
        final int looped = Integer.parseInt(properties.getProperty("looped"));
        final String version = properties.getProperty("version");
        final String option = properties.getProperty("option");

        TebUtilities.println(bw, "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" align=\"center\">");
        TebUtilities.println(bw, "<tr>");
        TebUtilities.println(bw, "    <td>");
        writePanel(bw, results, new PanelRender() {
            @Override
            public String getTitle() {
                return "TPS(Count/Second)";
            }

            @Override
            public long getValue(TebResult[] results, int index) {
                return looped * thread * 1000 / (results[index].getTime() == 0 ? 1 : results[index].getTime());
            }
        });
        TebUtilities.println(bw, "    </td>");
        TebUtilities.println(bw, "    <td>");
        writePanel(bw, results, new PanelRender() {
            @Override
            public String getTitle() {
                return "Time(Mill Second)";
            }

            @Override
            public long getValue(TebResult[] results, int index) {
                return results[index].getTime();
            }
        });
        TebUtilities.println(bw, "    </td>");
        TebUtilities.println(bw, "    <td>");
        writePanel(bw, results, new PanelRender() {
            @Override
            public String getTitle() {
                return "Once Output(" + (binary ? "byte" : "char") + ")";
            }

            @Override
            public long getValue(TebResult[] results, int index) {
                return results[index].getOnce();
            }
        });
        TebUtilities.println(bw, "    </td>");
        TebUtilities.println(bw, "    <td>");
        writePanel(bw, results, new PanelRender() {
            @Override
            public String getTitle() {
                return "Mass Output(" + (binary ? "byte" : "char") + ")";
            }

            @Override
            public long getValue(TebResult[] results, int index) {
                return results[index].getMass();
            }
        });
        TebUtilities.println(bw, "    </td>");
        TebUtilities.println(bw, "</tr>");
        TebUtilities.println(bw, "<tr>");
        TebUtilities.println(bw, "    <td colspan=\"4\">");
        TebUtilities.println(bw, "        <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"info\" align=\"center\">");
        TebUtilities.println(bw, "        <tr>");
        TebUtilities.println(bw, "            <td class=\"legend\">vm.ver</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">thread</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">record</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">warmed</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">looped</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">target</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">stream</td>");
        TebUtilities.println(bw, "        <tr>");
        TebUtilities.println(bw, "        <tr>");
        TebUtilities.println(bw, "            <td class=\"legend\">" + version + "</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">" + thread + "</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">" + record + "</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">" + warmed + "</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">" + looped + "</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">" + target + "</td>");
        TebUtilities.println(bw, "            <td class=\"legend\">" + (binary ? "byte" : "char") + " stream</td>");
        TebUtilities.println(bw, "        <tr>");
        TebUtilities.println(bw, "        <tr>");
        TebUtilities.println(bw, "            <td class=\"legend\" colspan=\"7\">option:" + option + "</td>");
        TebUtilities.println(bw, "        </tr>");
        TebUtilities.println(bw, "        </table>");
        TebUtilities.println(bw, "    </td>");
        TebUtilities.println(bw, "</tr>");

        TebUtilities.println(bw, "</table>");
    }

    private static void writePanel(BufferedWriter bw, TebResult[] results, PanelRender render) throws Exception {
        long max = Long.MIN_VALUE;
        for (int i = 0, n = results.length; i < n; i++) {
            max = Math.max(max, render.getValue(results, i));
        }
        TebUtilities.println(bw, "        <div class=\"subject\">" + render.getTitle() + "</div>");
        TebUtilities.println(bw, "        <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"panel\">");
        TebUtilities.println(bw, "        <tr>");
        long height, value;
        for (int i = 0, n = results.length; i < n; i++) {
            value = render.getValue(results, i);
            height = value * 150 / (max == 0 ? 150 : max);
            TebUtilities.println(bw, "            <td valign=\"bottom\"><div class=\"panel\" style=\"height:" + height + "px;background-color:" + COLORS[i] + "\" title=\"" + results[i].getName() + "=" + value + "\"></td>");
        }
        TebUtilities.println(bw, "        </tr>");
        TebUtilities.println(bw, "        </table>");
        TebUtilities.println(bw, "        <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"legend\">");
        String href = "";
        for (int i = 0, n = results.length; i < n; i++) {
            href = results[i].getSite();
            if (href != null && href.trim().length() > 0) {
                href = "<a href=\"" + href + "\">" + results[i].getName() + "</a>";
            } else {
                href = results[i].getName();
            }
            TebUtilities.println(bw, "        <tr>");
            TebUtilities.println(bw, "            <td valign=\"center\" align=\"center\" width=\"16px\"><div class=\"legend\" style=\"background-color:" + COLORS[i] + "\"></td>");
            TebUtilities.println(bw, "            <td class=\"legend\">" + href + "</td>");
            TebUtilities.println(bw, "            <td class=\"legend\">" + render.getValue(results, i) + "</td>");
            TebUtilities.println(bw, "        </tr>");
        }
        TebUtilities.println(bw, "        </table>");
    }
}
